package com.lfy.modules.blog.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.lfy.modules.blog.domain.LeaveMessageEntity;
import com.lfy.modules.blog.domain.dto.leave.LeaveMsgAdminDTO;
import com.lfy.modules.blog.domain.dto.leave.LeaveMsgDTO;
import com.lfy.modules.blog.domain.vo.web.LeaveMsgAdminVO;
import com.lfy.modules.blog.domain.vo.web.LeaveMsgVO;
import com.lfy.modules.blog.service.LeaveMessageService;
import com.lfy.modules.blog.mapper.BlogLeaveMessageMapper;
import com.lfy.modules.blog.service.UserService;
import com.lfy.modules.common.custom.constants.CommentEnum;
import com.lfy.modules.common.custom.constants.PageConstant;
import com.lfy.modules.common.domain.BaseEnum;
import com.lfy.modules.common.domain.PageResultVO;
import com.lfy.modules.common.domain.R;
import com.lfy.modules.common.domain.entity.UserEntity;
import com.lfy.modules.common.intercept.AuthHandlerInterceptor;
import com.lfy.modules.common.utils.PageUtil;

import com.lfy.modules.common.utils.RequestUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

/**
* @author 吕飞扬
* @description 针对表【blog_leave_message】的数据库操作Service实现
* @createDate 2024-06-28 23:35:33
*/
@Service
public class LeaveMessageServiceImpl extends ServiceImpl<BlogLeaveMessageMapper, LeaveMessageEntity>
    implements LeaveMessageService {
    @Resource
    private UserService userService;
    @Resource
    private ThreadPoolExecutor mainThreadPool;
    @Override
    public R<PageResultVO<LeaveMsgVO>> getLeaveMsgByPage(Integer pageNum, Integer pageSize, String url) {
        if(pageSize >= PageConstant.MAX_PAGE_SIZE){
            return R.error(BaseEnum.commonEnum.ERROR_PAGE_SIZE);
        }
        UserEntity user = this.userService.getOne(Wrappers.lambdaQuery(UserEntity.class).eq(UserEntity::getUrl, url));
        if(Objects.isNull(user)){
            return R.error(BaseEnum.authEnum.USER_NOT_EXIST);
        }
        Page<LeaveMessageEntity> entityPage = this.baseMapper.selectPage(new Page<LeaveMessageEntity>(pageNum, pageSize), Wrappers.<LeaveMessageEntity>lambdaQuery().eq(LeaveMessageEntity::getTenantId, user.getId())
                .eq(LeaveMessageEntity::getParentId, 0L).orderByDesc(LeaveMessageEntity::getCreateTime));
        List<LeaveMessageEntity> records = entityPage.getRecords();
        if(CollectionUtils.isEmpty(records)){
            return R.success(PageUtil.convert2PageEmptyResult(entityPage, LeaveMsgVO.class));
        }
        List<LeaveMsgVO> result = records.stream().map(item -> {
            LeaveMsgVO leaveMsgVO = new LeaveMsgVO();
            BeanUtils.copyProperties(item, leaveMsgVO);
            leaveMsgVO.setCreateTime(DateUtil.formatDateTime(item.getCreateTime()));
            return leaveMsgVO;
        }).collect(Collectors.toList());
        return R.success(PageUtil.buildPageResultVO(entityPage, result));
    }

    @Override
    public R<List<LeaveMsgVO>> getChildLeaveMsg(String url, Long parentMsgId) {
        UserEntity user = this.userService.getOne(Wrappers.lambdaQuery(UserEntity.class).eq(UserEntity::getUrl, url));
        if(Objects.isNull(user)){
            return R.error(BaseEnum.authEnum.USER_NOT_EXIST);
        }
        List<LeaveMessageEntity> records = this.baseMapper.selectList(Wrappers.<LeaveMessageEntity>lambdaQuery().eq(LeaveMessageEntity::getTenantId, user.getId())
                .eq(LeaveMessageEntity::getParentId, parentMsgId).orderByDesc(LeaveMessageEntity::getCreateTime));
        if(CollectionUtils.isEmpty(records)){
            return R.success(Collections.emptyList());
        }
        List<LeaveMsgVO> result = records.stream().map(item -> {
            LeaveMsgVO leaveMsgVO = new LeaveMsgVO();
            BeanUtils.copyProperties(item, leaveMsgVO);
            leaveMsgVO.setCreateTime(DateUtil.formatDateTime(item.getCreateTime()));
            return leaveMsgVO;
        }).collect(Collectors.toList());
        return R.success(result);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Void> addLeaveMsg(LeaveMsgDTO dto) {
        UserEntity user = this.userService.getOne(Wrappers.lambdaQuery(UserEntity.class).eq(UserEntity::getUrl, dto.getUrl()));
        if(Objects.isNull(user)){
            return R.error(BaseEnum.authEnum.USER_NOT_EXIST);
        }
        LeaveMessageEntity entity = new LeaveMessageEntity();
        BeanUtils.copyProperties(dto, entity);
        entity.setTenantId(user.getId());
        //TODO 敏感词处理
        entity.setCommentContentDesensitization(dto.getCommentContent());
        entity.setLikeCount(0);
        entity.setLikeCount(0);
        entity.setIsAuthor(CommentEnum.IS_NOT_AUTHOR.getCode());
        //ip
        String ip = RequestUtil.getIp();
        entity.setIp(ip);
        entity.setIpAddress(RequestUtil.getPlace(ip));

        if(dto.getParentId() != null){
            mainThreadPool.execute(() -> {
                LeaveMessageEntity parent = this.baseMapper.selectById(dto.getParentId());
                if(Objects.nonNull(parent)){
                    parent.setCommentCount(parent.getCommentCount() + 1);
                    this.baseMapper.updateById(parent);
                }
            });
        }
        this.baseMapper.insert(entity);
        return R.success();
    }

    @Override
    public R<Void> like(Long msgId,Integer type) {
        LeaveMessageEntity entity = this.baseMapper.selectById(msgId);
        if(Objects.isNull(entity)){
            return R.error("留言不存在");
        }
        if(type == 1){
            entity.setLikeCount(entity.getLikeCount() + 1);
        }else {
            entity.setLikeCount(entity.getLikeCount() - 1);
        }

        this.baseMapper.updateById(entity);
        return R.success();
    }

    @Override
    public R<PageResultVO<LeaveMsgAdminVO>> getLeaveMsgByAdmin(Integer pageNum, Integer pageSize, UserEntity user) {

        Page<LeaveMessageEntity> entityPage = this.baseMapper.selectPage(new Page<LeaveMessageEntity>(pageNum, pageSize), Wrappers.<LeaveMessageEntity>lambdaQuery()
                .eq(LeaveMessageEntity::getTenantId, user.getId()).eq(LeaveMessageEntity::getParentId, 0L).orderByDesc(LeaveMessageEntity::getCreateTime));
        List<LeaveMessageEntity> records = entityPage.getRecords();

        if(CollectionUtils.isEmpty(records)){
            return R.success(PageUtil.convert2PageEmptyResult(entityPage, LeaveMsgAdminVO.class));
        }
        List<LeaveMsgAdminVO> result = records.stream().map(item -> {
            LeaveMsgAdminVO leaveMsgAdminVO = new LeaveMsgAdminVO();
            BeanUtils.copyProperties(item, leaveMsgAdminVO);
            leaveMsgAdminVO.setCreateTime(DateUtil.formatDateTime(item.getCreateTime()));
            return leaveMsgAdminVO;
        }).collect(Collectors.toList());
        return R.success(PageUtil.buildPageResultVO(entityPage, result));
    }

    @Override
    @Transactional
    public R<Void> deleteLeaveMsg(Long id, UserEntity user) {
        this.baseMapper.deleteById(id);
        this.baseMapper.delete(Wrappers.<LeaveMessageEntity>lambdaQuery().eq(LeaveMessageEntity::getParentId, id));
        return R.success();
    }

    @Override
    public R<Void> replyLeaveMsg(LeaveMsgAdminDTO dto, UserEntity user) {
        LeaveMessageEntity entity = new LeaveMessageEntity();
        BeanUtils.copyProperties(dto, entity);
        entity.setTenantId(user.getId());
        //TODO 敏感词处理
        entity.setCommentContentDesensitization(dto.getCommentContent());
        entity.setLikeCount(0);
        entity.setLikeCount(0);
        entity.setIsAuthor(CommentEnum.IS_AUTHOR.getCode());
        //ip
        String ip = RequestUtil.getIp();
        entity.setIp(ip);
        entity.setIpAddress(RequestUtil.getPlace(ip));

        if(dto.getParentId() != null){
            mainThreadPool.execute(() -> {
                LeaveMessageEntity parent = this.baseMapper.selectById(dto.getParentId());
                if(Objects.nonNull(parent)){
                    parent.setCommentCount(parent.getCommentCount() + 1);
                    this.baseMapper.updateById(parent);
                }
            });
        }
        this.baseMapper.insert(entity);
        return R.success();
    }

    @Override
    public R<List<LeaveMsgAdminVO>> getChildrenLeaveMsg(Long id) {
        UserEntity user = AuthHandlerInterceptor.authLocal.get();
        List<LeaveMessageEntity> records = this.baseMapper.selectList(Wrappers.<LeaveMessageEntity>lambdaQuery().eq(LeaveMessageEntity::getTenantId, user.getId())
                .eq(LeaveMessageEntity::getParentId, id).orderByDesc(LeaveMessageEntity::getCreateTime));
        if(CollectionUtils.isEmpty(records)){
            return R.success(Collections.emptyList());
        }
        List<LeaveMsgAdminVO> result = records.stream().map(item -> {
            LeaveMsgAdminVO leaveMsgVO = new LeaveMsgAdminVO();
            BeanUtils.copyProperties(item, leaveMsgVO);
            leaveMsgVO.setCreateTime(DateUtil.formatDateTime(item.getCreateTime()));
            return leaveMsgVO;
        }).collect(Collectors.toList());
        return R.success(result);
    }


}




